﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using seqType = System.UInt64;  /// Type for sequence numbers

namespace ReliableSession.src
{
    public class TransportHeader
    {
        public enum BitFlags : ushort
        {
            SYN = 0x1,  /// Synchronization segment is present.
            ACK = 0x2,  /// Ack number in the header is valid.
            RST = 0x4,  /// Reset 
        }

        public ushort m_bitFlags;
        public ushort m_headerLength;
        public byte m_version;
        public byte m_zero;
        public seqType m_seqNumber;
        public seqType m_ackNumber;
        public ushort m_checksum;
        public ushort m_dataLength;

        public void deserialize(BinaryReader reader)
        {
            m_bitFlags = reader.ReadUInt16();
            m_headerLength = reader.ReadUInt16();
            m_version = reader.ReadByte();
            m_zero = reader.ReadByte();
            m_seqNumber = reader.ReadUInt16();
            m_ackNumber = reader.ReadUInt16();
            m_checksum = reader.ReadUInt16();
            m_dataLength = reader.ReadUInt16();
        }

        public void deserialize(FifoBuffer buffer)
        {
            m_bitFlags = buffer.readUshort();
            m_headerLength = buffer.readUshort();
            m_version = buffer.readByte();
            m_zero = buffer.readByte();
            m_seqNumber = buffer.readUshort();
            m_ackNumber = buffer.readUshort();
            m_checksum = buffer.readUshort();
            m_dataLength = buffer.readUshort();
        }

        public void serialize(BinaryWriter writer)
        {
            writer.Write(m_bitFlags);
            writer.Write(m_headerLength);
            writer.Write(m_version);
            writer.Write(m_zero);
            writer.Write(m_seqNumber);
            writer.Write(m_ackNumber);
            writer.Write(m_checksum);
            writer.Write(m_dataLength);
        }

        public void serialize(FifoBuffer writer)
        {
            writer.write(m_bitFlags);
            writer.write(m_headerLength);
            writer.write(m_version);
            writer.write(m_zero);
            writer.write(m_seqNumber);
            writer.write(m_ackNumber);
            writer.write(m_checksum);
            writer.write(m_dataLength);
        }


        public bool isBitSet(BitFlags flag)
        {
            bool set = false;
            set = (m_bitFlags & (ushort)flag) != 0;
            return set;
        }

        /// <summary>
        /// Clear the bit flags
        /// </summary>
        internal void clearBitFlag()
        {
            m_bitFlags = 0;
        }

        internal void setBit(BitFlags bitFlags)
        {
            m_bitFlags |= (ushort)bitFlags;
        }

        /// <summary>
        /// The to string if this header was received
        /// </summary>
        /// <returns></returns>
        public override String ToString()
        {
            String str = "PeerSeq=" + m_seqNumber + " PeerAck=" + m_ackNumber + " Len=" + m_dataLength + " Seq=" + m_seqNumber;
            return str;
        }
    }
}
